CHAPTER 2
In this chapter, we’ll look closely at the .NET runtime, called the common language runtime (CLR), and how it compiles and executes your code. In order to master Visual Basic (VB) devel-opment, it is important to understand the components that comprise the CLR and how they work. This helps you write more optimized code that performs better. In addition, under-standing how the CLR manages objects in memory helps you troubleshoot any performance issues that may arise. We’ll look at how VB is compiled and then how compilation to native code works. Finally, we’ll look at the assemblies and metadata—information about those assemblies—which the compiler creates.
VB applications are called managed applications because they are managed by the .NET runtime, the CLR. The CLR is an implementation of the Common Language Infrastructure
(CLI) standard. The CLI is a specification published by Ecma International, which defines the rules that a development infrastructure must follow in order to provide cross-language com-patibility and platform independence. According to the specification, it defines the CLI “in which applications written in multiple high-level languages may be executed in different sys-tem environments without the need to rewrite the applications to take into consideration the unique characteristics of those environments.”
The CLR is more than just a virtual execution system; it also provides services such as memory management, code safety verification, security and a strict system of data typing, the common type system (CTS). The just-in-time (JIT) compiler that translates intermediate language (IL) into CPU-specific assemblies is also part of the CLR.
The first thing that happens after you write VB code is that the VB compiler, vbc.exe, takes that code and generates IL. The IL that the compiler generates is contained in binaries, with the familiar EXE or DLL extension. This is where the similarity between .NET binaries and COM binaries ends. COM binaries contain platform-specific instructions and are described by a separate file called a type library. In contrast, .NET binaries contain IL that can be run on any platform, and they contain their own metadata.
The VB compiler, and any .NET language compiler for that matter, generates IL that must follow certain rules. This is where true language independence begins. Because IL follows certain rules, the CLR can understand IL generated from any high-level language. Hence, the CLR can understand code written in Visual Basic .NET (VB .NET) or COBOL.NET once it’s compiled into IL.
The .NET Framework SDK comes with a disassembler utility called the MSIL Disassembler. This utility allows you to peer into .NET binaries and see the IL that they contain. You can run the disassembler by navigating to Programs --> Microsoft .NET Framework SDK v2.0 --> Tools --> MSIL Disassembler. Figure 2-1 shows a screenshot of the utility.
If you run the utility, it displays a tree view of the type data from the assembly, so you’ll need to dump the IL to a file via the File --> Dump menus. As the following code shows, IL looks similar to assembly language; in essence, it’s the assembly language of the CLR:
.method public static void Main() cil managed { .entrypoint .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = (01 00 00 00) // Code size 14 (0xe) .maxstack 8 // Source File 'C:\Apress\Accelerated VB 2005\Projects\Hello World\EntryPoint.vb' //000002: Shared Sub Main()
IL_0000: nop //000003: System.Console.WriteLine("Hello World!")
IL_0001: ldstr "Hello World!"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop //000004: End Sub
IL_000c: nop
IL_000d: ret } // end of method EntryPoint::Main
As you scroll through the IL file, you’ll see that it completely describes the program in a low-level manner. It’s interesting to note that the IL for the same application written in C# would look very similar to the IL generated from the VB program.